<?php

namespace extend\oss;

class DirectTransfer extends Base
{
    /**
     * 获取授权信息
     * @param $request
     * @return array
     * @throws \Exception
     */
    public function authorize($request)
    {
        $config = $this->config;
        // 文件路径
        $filePath = $request['filePath'];
        // 文件大小
        $fileMax = $request['fileMax'] ?? 1048576000;
        // 过期时间
        $expire = $request['expire'] ?? 30;

        $expireTime = time() + $expire;
        $callbackBody = base64_encode(json_encode([
            'callbackUrl' => $request['callbackUrl'],
            'callbackBody' => 'filename=${object}&size=${size}&mimeType=${mimeType}&height=${imageInfo.height}&width=${imageInfo.width}',
            'callbackBodyType' => "application/x-www-form-urlencoded"
        ], JSON_UNESCAPED_UNICODE));

        $base64Policy = base64_encode(json_encode([
            'expiration' => $this->gmtIso8601($expireTime),
            'conditions' => [
                //最大文件大小.用户可以自己设置
                ['content-length-range', 0, $fileMax],
                // 表示用户上传的数据，必须是以$dir开始，不然上传会失败，这一步不是必须项，只是为了安全起见，防止用户通过policy上传到别人的目录
                ['starts-with', '$key', $filePath],
            ]], JSON_UNESCAPED_UNICODE));
        $signature = base64_encode(hash_hmac('sha1', $base64Policy, $config['accessKeySecret'], true));


        return [
            'accessid' => $config['accessKeyId'],
            'host' => $request['endpoint'] ?? $config['endpoint'],
            'policy' => $base64Policy,
            'signature' => $signature,
            'expire' => $expireTime,
            'callback' => $callbackBody,
            'path' => $filePath,
        ];

    }

    /**
     * 回调
     * @return bool|string
     */
    public function callback()
    {
        // 1.获取OSS的签名header和公钥url header
        $authorizationBase64 = $pubKeyUrlBase64 = '';
        if (isset($_SERVER['HTTP_AUTHORIZATION'])) {
            $authorizationBase64 = $_SERVER['HTTP_AUTHORIZATION'];
        }
        if (isset($_SERVER['HTTP_X_OSS_PUB_KEY_URL'])) {
            $pubKeyUrlBase64 = $_SERVER['HTTP_X_OSS_PUB_KEY_URL'];
        }
        if ($authorizationBase64 == '' || $pubKeyUrlBase64 == '') {
            return '授权验证参数失败';
        }

        // 2.获取OSS的签名
        $authorization = base64_decode($authorizationBase64);

        // 3.获取公钥
        $pubKeyUrl = base64_decode($pubKeyUrlBase64);
        $pubKey = file_get_contents($pubKeyUrl);
        if (empty($pubKey)) {
            return '获取公钥失败';
        }

        // 4.获取回调body
        $body = file_get_contents('php://input');

        // 5.拼接待签名字符串
        $path = $_SERVER['REQUEST_URI'];
        $pos = strpos($path, '?');
        if ($pos === false) {
            $authStr = urldecode($path) . "\n" . $body;
        } else {
            $authStr = urldecode(substr($path, 0, $pos)) . substr($path, $pos, strlen($path) - $pos) . "\n" . $body;
        }

        // 6.验证签名
        $response = openssl_verify($authStr, $authorization, $pubKey, OPENSSL_ALGO_MD5);
        if ($response == 1) {
            return true;
        } else {
            return '验证签名失败';
        }
    }
}